#include <gtkmm/liststore.h>
#include <gtkmm/treemodelcolumn.h>

#include "ModuleConnection.h"
#include "ServiceConnection.h"
#include "ServiceManager.h"
#include "App.h"
#include "Mainwin.h"
#include "Global.h"

namespace Gnodroid {

    ModuleConnection::ModuleConnection() :
        Glib::ObjectBase("gnd_module_connection"),
        Module(MODULE_CONNECTION)
    {}

    void
    ModuleConnection::start()
    {
        __init();

        ServiceConnection* service = static_cast<ServiceConnection*>(
            App::getCurrentApp()->getServiceManager()
                ->getService(SERVICE_CONNECTION));
        //检查adb是否存在
        if (!service->checkAdb()) {
            LOG_ERROR("check adb failed");
            //todo : some process to set adb path
            //       or exit
        }

        __refreshDeviceList();
    }

    void
    ModuleConnection::stop()
    {}

    void
    ModuleConnection::__refreshDeviceList()
    {
        /*
        Glib::RefPtr<Gtk::Builder> builder =
            App::getCurrentApp()->getMainwin()->getBuilder();
        Gtk::ComboBox* pCbbox;
        builder->get_widget("cbbox_device_list", pCbbox);

        Gtk::TreeModelColumnRecord record;
        Gtk::TreeModelColumn<Glib::ustring> deviceModel;
        record.add(deviceModel);
        */

        auto listStore = Gtk::ListStore::create(m_deviceColumns);

        auto serviceConnection = static_cast<ServiceConnection*>(App::getCurrentApp()
            ->getServiceManager()
            ->getService(SERVICE_CONNECTION));
        //获取设备列表
        auto deviceList = serviceConnection->getDeviceList();

        for (auto it = deviceList->begin();
             it != deviceList->end();
             it ++) {
            auto row = *(listStore->append());
            row[m_deviceColumns.model] = it->model;
            row[m_deviceColumns.id] = it->id;

        }

        m_pCbboxDeviceList->set_model(listStore);
        m_pCbboxDeviceList->set_active(0);
/*
        auto it = listStore->append();
        auto row = *it;
        row[m_deviceColumns.model] = "zuk z2";
        row[m_deviceColumns.id] = "000001";
        it = listStore->append();
        row = *it;
        row[m_deviceColumns.model] = "lenove";
        row[m_deviceColumns.id] = "000002";

        m_pCbboxDeviceList->set_active(0);
        m_pCbboxDeviceList->set_model(listStore);
*/
        //pCbbox->pack_start(deviceModel);
    }

    void
    ModuleConnection::__init()
    {
        ServiceConnection* service = static_cast<ServiceConnection*>(
            App::getCurrentApp()->getServiceManager()
                ->getService(SERVICE_CONNECTION));
        Mainwin* mainwin = App::getCurrentApp()
            ->getMainwin();
        Glib::RefPtr<Gtk::Builder> builder = mainwin->getBuilder();

        builder->get_widget("cbbox_device_list", m_pCbboxDeviceList);
        builder->get_widget("btn_connect", m_pBtnConnect);
        builder->get_widget("btn_refresh", m_pBtnRefresh);

        //连接按钮信号
        m_pBtnRefresh->signal_clicked()
            .connect(sigc::mem_fun(*this, &ModuleConnection::__onRefresh));
        m_pBtnConnect->signal_clicked()
            .connect(sigc::mem_fun(*this, &ModuleConnection::__onConnect));
        //m_pCbboxDeviceList->set_model(m_deviceColumns);
        m_pCbboxDeviceList->pack_start(m_deviceColumns.model);


        //get the signal of connect status
        //连接状态信号
        service->signal_connected().connect([this](std::string id){
            LOG("signal connect");
            LOG(id);
            __switchStatus(STATUS_CONNECTED);
        });
        service->signal_connectfailed().connect([this](std::string id){
            LOG("signal connectfailed");
            LOG(id);
            __switchStatus(STATUS_DISCONNECTED);
        });
        service->signal_disconnected().connect([this](std::string id){
            LOG("signal disconnect");
            LOG(id);
            __switchStatus(STATUS_DISCONNECTED);
        });

    }

    void
    ModuleConnection::__onRefresh()
    {
        __refreshDeviceList();
    }

    void
    ModuleConnection::__onConnect()
    {
        //todo : connect
        LOG("connect");
        ServiceConnection* service = static_cast<ServiceConnection*>(App::getCurrentApp()
            ->getServiceManager()->getService(SERVICE_CONNECTION));

        //service->connect("emulator-5554");
        //根据当前状态决定按钮动作
        switch (m_eConnectionStatus) {
        case STATUS_CONNECTED:
            service->disconnect();
            __switchStatus(STATUS_DISCONNECTED);
            break;
        case STATUS_CONNECTING:
            LOG_ERROR("you can clicked it if is connecting");
            break;
        case STATUS_DISCONNECTED:
            auto it = m_pCbboxDeviceList->get_active();
            if (!it) {
                LOG_WARN("no device chosen");
                break;
            }
            auto row = *it;
            Glib::ustring id = row[m_deviceColumns.id];
            service->connect(id);
            __switchStatus(STATUS_CONNECTING);
            break;
        }

    }


    void
    ModuleConnection::__switchStatus(ConnectionStatus status)
    {
        if (m_eConnectionStatus == status) {
            return;
        }
        m_eConnectionStatus = status;

        switch (status) {
        case STATUS_CONNECTED:
            m_pBtnConnect->set_sensitive(true);
            m_pBtnConnect->set_image_from_icon_name("media-playback-stop-symbolic");
            LOG("now connected");
            break;
        case STATUS_CONNECTING:
            m_pBtnConnect->set_sensitive(false);
            LOG("now connecting");
            break;
        case STATUS_DISCONNECTED:
            m_pBtnConnect->set_sensitive(true);
            m_pBtnConnect->set_image_from_icon_name("media-playback-start-symbolic");
            LOG("now disconnect");
            break;
        }
    }

}
